package services

import (
    "encoding/json"
    "sync"
    "time"
    "volux/utils"
)

type ConfigService struct {
    mu         sync.RWMutex
    etcdClient *utils.EtcdClient
    configs    map[string]*ConfigItem
    watchers   map[string][]ConfigChangeHandler
}

type ConfigItem struct {
    Key       string      `json:"key"`
    Value     interface{} `json:"value"`
    Version   int64       `json:"version"`
    UpdatedAt time.Time   `json:"updated_at"`
}

type ConfigChangeHandler func(item *ConfigItem)

func NewConfigService(etcdClient *utils.EtcdClient) *ConfigService {
    cs := &ConfigService{
        etcdClient: etcdClient,
        configs:    make(map[string]*ConfigItem),
        watchers:   make(map[string][]ConfigChangeHandler),
    }
    go cs.watchChanges()
    return cs
}

func (cs *ConfigService) Set(key string, value interface{}) error {
    cs.mu.Lock()
    defer cs.mu.Unlock()

    item := &ConfigItem{
        Key:       key,
        Value:     value,
        UpdatedAt: time.Now(),
    }

    data, err := json.Marshal(item)
    if err != nil {
        return err
    }

    if err := cs.etcdClient.Put("/config/"+key, string(data)); err != nil {
        return err
    }

    cs.configs[key] = item
    return nil
}

func (cs *ConfigService) Get(key string) (interface{}, error) {
    cs.mu.RLock()
    defer cs.mu.RUnlock()

    if item, exists := cs.configs[key]; exists {
        return item.Value, nil
    }

    // 从etcd加载
    data, err := cs.etcdClient.Get("/config/" + key)
    if err != nil {
        return nil, err
    }

    var item ConfigItem
    if err := json.Unmarshal([]byte(data), &item); err != nil {
        return nil, err
    }

    cs.configs[key] = &item
    return item.Value, nil
}

func (cs *ConfigService) Watch(key string, handler ConfigChangeHandler) {
    cs.mu.Lock()
    defer cs.mu.Unlock()

    if _, exists := cs.watchers[key]; !exists {
        cs.watchers[key] = make([]ConfigChangeHandler, 0)
    }
    cs.watchers[key] = append(cs.watchers[key], handler)
}

func (cs *ConfigService) watchChanges() {
    // TODO: 实现etcd watch机制
}
